#include "GeneradorDeVariables.h"
#include<iostream>
#include<cassert>

GeneradorDeVariables::GeneradorDeVariables(std::string path_a_archivo)
 : variablesPorDia(0, std::vector<VariableClimatica*>(15,(VariableClimatica*)NULL))
{printf("%s\n", "se contruye el genvar");
	std::ifstream archivoDeVariables(path_a_archivo.c_str());
	std::string linea;
	if (archivoDeVariables.is_open())
	{
		while (!archivoDeVariables.eof())
		{
			getline(archivoDeVariables, linea);
			parsear(linea);
		}
	}	
}

GeneradorDeVariables::~GeneradorDeVariables()
{
	for(unsigned i=0; i<variablesPorDia.size();i++)
		for(unsigned j=0; j<variablesPorDia[i].size();j++)
			delete variablesPorDia[i][j];
}

void GeneradorDeVariables::generarVariable(unsigned dia, std::string nombreVar, std::string& cadena)
{
	cadena.clear();
	std::vector<tAtribVariables> variables; 
	tAtribVariables var;
	VariableClimatica* variableAGenerar = obtenerVariable(dia,nombreVar);
	for(unsigned i=0; i<20; i++)
		for(unsigned j=0; j<15; j++)
		{
	    	var.setX(i);
	    	var.setY(j);
	    	var.setValor(variableAGenerar->generarValor());
	    	variables.push_back(var);
		}
	cadena = ParserXML::generarXML(variables, nombreVar);
}

VariableClimatica* GeneradorDeVariables::obtenerVariable(unsigned dia, std::string nombreVar)
{
	bool encontrado = false;
	VariableClimatica* retorno=NULL;
	for(unsigned i=0; i<variablesPorDia.size() && !encontrado; i++)
	{
		if (variablesPorDia[i].at(0)->getNombre() == nombreVar)
		{
			retorno = variablesPorDia[i][dia];
			encontrado = true;
		}
	}             assert(retorno!=NULL);
	return retorno;
}

int GeneradorDeVariables::parsear(std::string linea)
{

		unsigned posEspacio = linea.find(' ');
		std::string nombre = linea.substr(0,posEspacio);
		char tipo =linea.at(posEspacio+1);
		if (tipo=='D')
		{
			std::vector<double> valores;
			ObtenerValores(linea.substr(posEspacio+3), valores);
			unsigned size = variablesPorDia.size();
			variablesPorDia.resize(size+1);
			for(unsigned i=0; i<15; i++)
			{
				variablesPorDia[size].push_back(new VariableClimaticaDiscreta(nombre, valores[i]));
			}
		}
		if (tipo=='C')
		{
			std::vector<double> minimos, maximos;
			ObtenerValores(linea.substr(posEspacio+3), maximos, minimos);
			unsigned size = variablesPorDia.size();
			variablesPorDia.resize(size+1);
			for(unsigned i=0; i<15; i++)
			{
				variablesPorDia[size].push_back(new VariableClimaticaContinua(nombre, minimos[i], maximos[i]));
			}
		}
	
	return 0;
}

std::string escribir(std::string nombre, std::vector<double> valores)
{
    std::string linea;
    linea = nombre;
    linea += ' ';
    linea += 'D';
    linea += ' ';
    std::string valor;
    for (unsigned i=0; i<valores.size()-1; i++)
    {
        std::stringstream ss;
        ss<<valores[i];
        ss>>valor;
        linea += valor;
        linea += ',';
    }
    std::stringstream ss;
    ss<<valores[14];
    ss>>valor;
    linea += valor;
    linea += ';';
    
    return linea;
}

std::string escribir(std::string nombre, std::vector<double> max, std::vector<double> min)
{
    std::string linea;
    linea = nombre;
    linea += ' ';
    linea += 'C';
    linea += ' ';
    std::string valor;
    for (unsigned i=0; i<15-1; i++)
    {
        std::stringstream ss, ss_aux;
        ss<<min[i];
        ss>>valor;
        linea += valor;
        linea += '-';
        ss_aux<<max[i];
        ss_aux>>valor;
        linea += valor;
        linea += ',';
    }
    std::stringstream ss, ss_aux;
    ss<<min[14];
    ss>>valor;
    linea += valor;
    linea += '-';
    ss_aux<<max[14];
    ss_aux>>valor;
    linea += valor;
    linea += ';';
    
    return linea; 
}

void GeneradorDeVariables::ObtenerValores(std::string linea, std::vector<double>& valores)
{
     valores.clear();
     unsigned posComa;
     unsigned inicio = 0;
     bool fin = false;
     while (!fin)
     {
         posComa = linea.find(',', inicio);
         if (posComa == std::string::npos)
         {
             posComa = linea.find(';');
             fin = true;
         }
         valores.push_back(atof((linea.substr(inicio, posComa-inicio)).c_str()));
         inicio = posComa + 1;
     }     
}

void GeneradorDeVariables::ObtenerValores(std::string linea, std::vector<double>& max, std::vector<double>& min)
{
     max.clear();
     min.clear();
     unsigned posComa;
     unsigned inicio = 0;
     bool fin = false;
     while (!fin)
     {
         posComa = linea.find(',', inicio);
         if (posComa == std::string::npos)
         {
             posComa = linea.find(';');
             fin = true;
         }
         std::string rango = linea.substr(inicio, posComa-inicio); 
         min.push_back(atof((rango.substr(0,rango.find('-'))).c_str()));
         max.push_back(atof((rango.substr(rango.find('-')+1)).c_str()));
         inicio = posComa + 1;
     }     
}

   
